package com.heima.wemedia.service.impl;

import com.heima.apis.article.IArticleClient;
import com.heima.apis.user.IUserClient;
import com.heima.model.article.dtos.ArticleCommentDto;
import com.heima.model.comment.dto.CommentConfigDto;
import com.heima.model.comment.dto.CommentLikeDto;
import com.heima.model.comment.dto.CommentManageDto;
import com.heima.model.comment.dto.CommentRepaySaveDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.AppThreadLocalUtil;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.pojos.*;
import com.heima.wemedia.service.CommentManageService;
import com.mongodb.client.result.UpdateResult;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CommentManageServiceImpl implements CommentManageService {

    private final MongoTemplate mongoTemplate;

    private final IUserClient userClient;

    private final IArticleClient articleClient;

    private final WmUserMapper wmUserMapper;
    /**
     * 查看评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(CommentManageDto dto) {
        // 1.检查参数
        if (dto == null || dto.getArticleId() == null || dto.getArticleId() < 1){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        //2.判断是否登录
        WmUser user = WmThreadLocalUtil.getUser();
        if (user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //3.查询数据
        ApUser apUser = userClient.findUserById(user.getId());
        if (apUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST);
        }
        //构造查询条件
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()));
        PageRequest pageRequest = PageRequest.of(dto.getPage(), dto.getSize());
        query.with(pageRequest);
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        if (apComments.isEmpty()){
            return ResponseResult.okResult(apComments);
        }
        List<CommentRepayListVo> commentRepayListVos =new ArrayList<>();
        for (ApComment apComment : apComments) {
            CommentRepayListVo commentRepayListVo = new CommentRepayListVo();
            BeanUtils.copyProperties(apComment,commentRepayListVo);
            Query query1 = Query.query(Criteria.where("commentId").is(apComment.getId()));
            query1.with(Sort.by(Sort.Direction.DESC, "createdTime"));
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query1, ApCommentRepay.class);
            if (!apCommentRepays.isEmpty()){
                commentRepayListVo.setApCommentRepays(apCommentRepays);
            }
            commentRepayListVos.add(commentRepayListVo);
        }
        return ResponseResult.okResult(commentRepayListVos);
    }
    /**
     * 打开或关闭评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult updateCommentStatus(CommentConfigDto dto) {
        //1.检查参数
        if (dto == null || dto.getArticleId() == null || dto.getOperation() == null || dto.getArticleId() < 1 || dto.getOperation() < 0 || dto.getOperation() > 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmUser user = WmThreadLocalUtil.getUser();
        if (user == null || user.getApUserId() < 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (dto.getOperation() == 1) {
            // 开启评论时仅更新配置
            return articleClient.updateCommentStatus(dto);
        }
        Integer apUserId = user.getApUserId();
        // 批量获取评论ID
        List<ApComment> comments = mongoTemplate.find(
                Query.query(Criteria.where("entryId").is(dto.getArticleId())),
                ApComment.class
        );
        List<String> commentIds = comments.stream().map(ApComment::getId).collect(Collectors.toList());

        // 批量删除关联数据
        mongoTemplate.remove(
                Query.query(Criteria.where("commentRepayId").in(commentIds).and("authorId").is(apUserId)),
                ApCommentRepayLike.class
        );
        mongoTemplate.remove(
                Query.query(Criteria.where("commentId").in(commentIds).and("authorId").is(apUserId)),
                ApCommentRepay.class
        );
        mongoTemplate.remove(
                Query.query(Criteria.where("commentId").in(commentIds).and("authorId").is(apUserId)),
                ApCommentLike.class
        );

        // 删除主评论
        mongoTemplate.remove(
                Query.query(Criteria.where("entryId").is(dto.getArticleId()).and("authorId").is(apUserId)),
                ApComment.class
        );

        return articleClient.updateCommentStatus(dto);

    }
    /**
     * 查询文章评论列表
     * @param dto
     * @return
     */
    @Override
    public PageResponseResult findNewsComments(ArticleCommentDto dto) {
        if (dto == null ){
            return (PageResponseResult) ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmUser wmUser = WmThreadLocalUtil.getUser();
        if (wmUser == null){
            return (PageResponseResult) ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        dto.checkParam();
        dto.setWmUserId(wmUser.getId());
        return articleClient.findNewsComments(dto);
    }

    /**
     * 评论回复
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        //1.检查参数
        if (dto == null || dto.getCommentId() == null || dto.getContent() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getContent().length() > 140 ){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论内容不能超过140个字符");
        }
        //2.判断是否登录
        //获取自媒体人信息
        WmUser wmUser = WmThreadLocalUtil.getUser();
        WmUser dbUser = wmUserMapper.selectById(wmUser.getId());
        if(dbUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //3.安全检查 自行实现

        //4.保存评论
        //获取app端用户信息
        ApUser apUser = userClient.findUserById(dbUser.getApUserId());
        if (apUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"用户信息有误");
        }
        //构建评论对象
        ApCommentRepay commentRepay = ApCommentRepay.builder()
                .authorId(apUser.getId())
                .authorName(apUser.getName())
                .commentId(dto.getCommentId())
                .content(dto.getContent())
                .createdTime(new Date())
                .likes(0)
                .build();
        ApCommentRepay save = mongoTemplate.save(commentRepay);
        if (save.getId() == null ){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"评论回复失败");
        }
        //5更新回复数量
        mongoTemplate.updateFirst(
                Query.query(Criteria.where("_id").is(dto.getCommentId())), // 查询条件
                new Update().inc("reply", 1), // 增加reply字段的值
                ApComment.class // 目标文档类型
        );
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除评论
     * @param commentId
     * @return
     */
    @Override
    public ResponseResult delComment(String commentId) {
        if (StringUtils.isBlank(commentId)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论ID不能为空");
        }
        //删除评论
        mongoTemplate.remove(Query.query(Criteria.where("id").is(commentId)),ApComment.class);
        //删除该评论的所有的回复内容
        mongoTemplate.remove(Query.query(Criteria.where("commentId").is(commentId)),ApCommentRepay.class);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除评论回复
     *
     * @param commentRepayId
     * @return
     */
    @Override
    public ResponseResult delCommentRepay(String commentRepayId) {
        if (StringUtils.isBlank(commentRepayId)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"评论回复ID不能为空");
        }
        //删除评论回复
        mongoTemplate.remove(Query.query(Criteria.where("commentId").is(commentRepayId)),ApCommentRepay.class);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 评论点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1.检查参数
        if (dto == null || dto.getCommentId() == null || dto.getOperation() == null || dto.getOperation() < 0 || dto.getOperation() > 1){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.判断是否登录
        WmUser wmUser = WmThreadLocalUtil.getUser();
        WmUser dbUser = wmUserMapper.selectById(wmUser.getId());
        if(dbUser == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //获取app端用户信息
        ApUser apUser = userClient.findUserById(dbUser.getApUserId());
        //构造查询条件
        Update update = new Update().inc("likes", dto.getOperation() == 0 ? 1 : -1);
        Query query = new Query(Criteria.where("_id").is(dto.getCommentId()));
        //3.点赞
        if (dto.getOperation() == 0){
            //更新评论点赞数量
            UpdateResult updateResult = mongoTemplate.updateFirst(query, update, ApComment.class);
            if (updateResult.getModifiedCount() ==0){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "点赞失败");
            }
            //保存评论点赞数据
            ApCommentLike apCommentRepayLike = ApCommentLike.builder()
                    .commentId(dto.getCommentId())
                    .authorId(apUser.getId())
                    .build();
            mongoTemplate.save(apCommentRepayLike);
        } else if (dto.getOperation() == 1){
            //更新评论点赞数量
            UpdateResult updateResult = mongoTemplate.updateFirst(query, update, ApComment.class);
            if (updateResult.getModifiedCount() ==0){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "取消点赞失败");
            }
            //删除评论点赞数据
            Query query1 = Query.query(Criteria.where("commentRepayId").is(dto.getCommentId()).and("authorId").is(apUser.getId()));
            mongoTemplate.remove(query1);
        }
        //4.返回结果
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        Map<String, Object> result = new HashMap<>();
        if (apComment != null) {
            result.put("likes", apComment.getLikes());
        }
        return ResponseResult.okResult(result);
    }
}
